package club.ruanx.movie.controller;

import club.ruanx.acl.common.exception.UserException;
import club.ruanx.acl.entity.SysUser;
import club.ruanx.acl.enumeration.SysUserStatusEnum;
import club.ruanx.acl.service.SysUserService;
import club.ruanx.acl.vo.SysUserVO;
import club.ruanx.bean.ResultVO;
import club.ruanx.core.exception.TargetEntityNotFound;
import club.ruanx.exception.BaseException;
import club.ruanx.movie.controller.param.RegUserParam;
import club.ruanx.movie.param.MovieUserParam;
import club.ruanx.movie.service.UserFavoriteService;
import club.ruanx.movie.service.UserRateService;
import club.ruanx.security.bean.UserAuthInfo;
import club.ruanx.security.bean.UserAuthInfoContextHolder;
import club.ruanx.util.BeanUtils;
import club.ruanx.util.MD5Util;
import com.alibaba.fastjson.JSONObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.Min;

/**
 * @author 阮胜
 * @date 2018/11/24 20:40
 */
@RestController
@RequestMapping("/user")
public class UserController {

    private final SysUserService sysUserService;
    private final UserFavoriteService userFavoriteService;
    private final UserRateService userRateService;

    public UserController(SysUserService sysUserService, UserFavoriteService userFavoriteService, UserRateService userRateService) {
        this.sysUserService = sysUserService;
        this.userFavoriteService = userFavoriteService;
        this.userRateService = userRateService;
    }

    @GetMapping("/details")
    @PreAuthorize("hasAnyRole('USER')")
    public SysUserVO userInfo() throws UserException, TargetEntityNotFound {
        UserAuthInfo user = UserAuthInfoContextHolder.getCurrentUserAuthInfoThrow();
        SysUser sysUser = sysUserService.findById(user.getUid());
        SysUserVO sysUserVO = new SysUserVO();
        BeanUtils.copyPropertiesIgnoreNull(sysUser, sysUserVO);
        return sysUserVO;
    }

    @PostMapping("/changePwd")
    @PreAuthorize("hasAnyRole('USER')")
    public ResultVO changePwd(@RequestBody JSONObject json) throws UserException, TargetEntityNotFound {
        String rawPwd = json.getString("rawPwd");
        String newPwd = json.getString("newPwd");
        UserAuthInfo user = UserAuthInfoContextHolder.getCurrentUserAuthInfoThrow();
        SysUser sysUser = sysUserService.findById(user.getUid());
        if (sysUser.getPassword().equals(rawPwd)) {
            sysUser.setPassword(newPwd);
            sysUserService.save(sysUser);
            return ResultVO.builder().success(true).message("密码修改成功").build();
        }
        return ResultVO.builder().success(false).message("原始密码不正确").build();
    }

    @PostMapping("/save")
    @PreAuthorize("hasAnyRole('USER','SUPERADMIN')")
    public SysUserVO save(@RequestBody @Valid MovieUserParam movieUserParam) throws TargetEntityNotFound, UserException {
        String uid = UserAuthInfoContextHolder.getCurrentUserAuthInfoThrow().getUid();
        SysUser sysUser = sysUserService.findById(uid);
        BeanUtils.copyPropertiesIgnoreNull(movieUserParam, sysUser);
        sysUserService.save(sysUser);
        SysUserVO sysUserVO = new SysUserVO();
        BeanUtils.copyPropertiesIgnoreNull(sysUser, sysUserVO);
        return sysUserVO;
    }

    @PostMapping("/register")
    public ResultVO register(@RequestBody @Valid RegUserParam regUserParam) {
        if (sysUserService.checkUsernameExists(regUserParam.getUsername(), "")) {
            return ResultVO.builder().success(false).message("该用户名已被其他帐号绑定").build();
        }
        if (sysUserService.checkEmailExists(regUserParam.getEmail(), "")) {
            return ResultVO.builder().success(false).message("该邮箱已被其他帐号绑定").build();
        }
        SysUser user = SysUser.builder()
                .username(regUserParam.getUsername())
                .password(MD5Util.encript(regUserParam.getPassword()))
                .email(regUserParam.getEmail())
                .currentIntegral(0)
                .totalIntegral(0)
                .status(SysUserStatusEnum.AVAILABLE.getCode())
                .nickname(regUserParam.getUsername())
                .deptId(0)
                .roles("2")
                .build();
        sysUserService.save(user);
        return ResultVO.builder().success(true).message("用户注册成功").build();
    }

    @GetMapping("/favorite/{movieId}")
    @PreAuthorize("hasAnyRole('USER')")
    public ResultVO favorite(@PathVariable String movieId) throws UserException {
        userFavoriteService.favorite(movieId);
        return ResultVO.builder().success(true).message("收藏成功").build();
    }

    @GetMapping("/unfavorite/{movieId}")
    @PreAuthorize("hasAnyRole('USER')")
    public ResultVO unfavorite(@PathVariable String movieId) throws BaseException {
        userFavoriteService.unfavorite(movieId);
        return ResultVO.builder().success(true).message("取消收藏成功").build();
    }

    @GetMapping("/isfavorite/{movieId}")
    public ResultVO isfavorite(@PathVariable String movieId) throws BaseException {
        return ResultVO.builder().success(userFavoriteService.isfavorite(movieId)).build();
    }

    @GetMapping("/rate/{movieId}/{rate}")
    @PreAuthorize("hasAnyRole('USER')")
    public ResultVO rate(@PathVariable String movieId, @PathVariable @Min(1) Integer rate) throws UserException {
        userRateService.rate(movieId, rate);
        return ResultVO.builder().success(true).message("评分成功").build();
    }

}
